package malagaAcoge.controller.beans;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.StringTokenizer;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletResponse;

import malagaAcoge.controller.daos.AbogadoDao;
import malagaAcoge.controller.daos.ContactoViviendaDao;
import malagaAcoge.controller.daos.DemandaDao;
import malagaAcoge.controller.daos.IntervencionDao;
import malagaAcoge.controller.daos.DepartamentoDao;
import malagaAcoge.controller.daos.DocumentoDao;
import malagaAcoge.model.entities.Abogado;
import malagaAcoge.model.entities.Contactovivienda;
import malagaAcoge.model.entities.Demanda;
import malagaAcoge.model.entities.Intervencion;
import malagaAcoge.model.entities.Departamento;
import malagaAcoge.model.entities.Documento;
import malagaAcoge.model.entities.Ofertavivienda;
import malagaAcoge.model.entities.Tecnico;
import malagaAcoge.utils.Messages;

import org.primefaces.event.FileUploadEvent;
import org.primefaces.event.RowEditEvent;

public class IntervencionesBean {
	private Tecnico currentTecnico;
	private Intervencion intervencion;
	private Date fecha;
	private Intervencion intervencionSeleccionada;
	private Demanda demanda;
	private HashMap<String, byte[]> documentosInt;
	private List<String> nombresDocumentos;
	private String documento;
	private String path;
	private List<Intervencion> intervencionsDeDepartamentos;
	private Documento documentoAEliminar;
	private Intervencion intervencionAmodificar;
	private Intervencion intervencionOferta;
	private SimpleDateFormat sdf = new SimpleDateFormat(
			Messages.getString("DemandasBean.formatoFecha"));
	private String cadenaUsuario;
	private String departamento;
	private String cadenaTecnico;
	private HashMap<String, String> nombreDepartamentos;
	private Ofertavivienda ofertaSeleccionada;
	private Ofertavivienda nuevaOferta;
	private String nombreContacto;

	public IntervencionesBean() {
		setCurrentTecnico((Tecnico) FacesContext.getCurrentInstance()
				.getExternalContext().getSessionMap().get("tecnico")); //$NON-NLS-1$
		intervencion = new Intervencion();
		nuevaOferta = new Ofertavivienda();
		if (getDocumentosInt() == null) {
			documentosInt = new HashMap<String, byte[]>();
			FacesContext.getCurrentInstance().getExternalContext()
					.getSessionMap().put("documentosInt", documentosInt);
		}
	}

	public void handleFileUpload(FileUploadEvent event) {
		getDocumentosInt();
		documentosInt.put(event.getFile().getFileName(), event.getFile()
				.getContents());
		FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
				.put("documentosInt", documentosInt); //$NON-NLS-1$
		FacesMessage msg = new FacesMessage("Exito", event.getFile() //$NON-NLS-1$
				.getFileName() + " subido con exito."); //$NON-NLS-1$
		FacesContext.getCurrentInstance().addMessage(null, msg);
	}

	private boolean guardarArchivo(byte[] archivo, String nombre,
			int idIntervencion) {
		boolean ok = false;
		try {
			File file = new File(
					Messages.getString("IntervencionsBean.directorio") + idIntervencion); //$NON-NLS-1$
			if (!file.exists()) {
				file.mkdirs();
			}
			file = new File(
					Messages.getString("IntervencionsBean.directorio") + idIntervencion + "\\" + nombre); //$NON-NLS-1$ //$NON-NLS-2$
			FileOutputStream fos = new FileOutputStream(file);
			fos.write(archivo);
			fos.flush();
			fos.close();
			ok = true;
		} catch (Exception e) {
			System.out.println("Problema al guardar el fichero: " + nombre); //$NON-NLS-1$
		}
		return ok;
	}

	public void addOferta() {
		nuevaOferta.setTecnicoBean(currentTecnico);
		intervencionOferta = (Intervencion) FacesContext.getCurrentInstance()
				.getExternalContext().getSessionMap()
				.remove("intervencionOferta");
		nuevaOferta.setUsuarioBean(intervencionOferta.getUsuarioBean());
		nuevaOferta.setIntervencionBean(intervencionOferta);
		new ContactoViviendaDao();
		nuevaOferta.setContactovivienda(ContactoViviendaDao
				.findContactoviviendaByExactName(nombreContacto));
		new IntervencionDao();
		IntervencionDao.createOfertaVivienda(nuevaOferta);
		intervencionOferta.setOfertaviviendas(new ArrayList<Ofertavivienda>());
		intervencionOferta.getOfertaviviendas().add(nuevaOferta);
		IntervencionDao.mergeIntervencion(intervencionOferta);
		intervencionOferta = new Intervencion();
		nuevaOferta = new Ofertavivienda();
		getIntervencionsDeDepartamentos();
	}

	public void addIntervencion() {
		new IntervencionDao();
		intervencion.setUsuarioBean(getDemanda().getUsuarioBean());
		intervencion.setTecnicoBean(currentTecnico);
		intervencion.setFecha(sdf.format(fecha));
		intervencion.setDemandaBean(demanda);
		IntervencionDao.createIntervencion(intervencion);
		if (getDocumentosInt() != null) {
			List<Documento> documentosList = new ArrayList<Documento>();
			for (String nombre : documentosInt.keySet()) {
				Documento documento = new Documento();
				documento.setTipo(nombre);
				documento.setFecha(sdf.format(new Date()));
				documento.setIntervencionBean(intervencion);
				if (guardarArchivo(documentosInt.get(nombre), nombre,
						intervencion.getIdIntervencion())) {
					new DocumentoDao();
					DocumentoDao.createDocumento(documento);
					documentosList.add(documento);
				}
			}
			intervencion.setDocumentos(documentosList);
			new IntervencionDao();
			IntervencionDao.mergeIntervencion(intervencion);
		}
		new DemandaDao();
		demanda.setEstado("Solucionada");
		demanda.setFechaModificacion(sdf.format(new Date()) + " ["
				+ getCurrentTecnico().getNombre() + " "
				+ getCurrentTecnico().getApellidos() + "]");
		if (demanda.getIntervencions() == null) {
			demanda.setIntervencions(new ArrayList<Intervencion>());
		}
		demanda.getIntervencions().add(intervencion);
		DemandaDao.mergeDemanda(demanda);
		FacesContext context = FacesContext.getCurrentInstance();
		context.addMessage(null, new FacesMessage("Exito", //$NON-NLS-1$
				"Intervencion registrada correctamente.")); //$NON-NLS-1$
		intervencion = new Intervencion();
		FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
				.put("documentosInt", new HashMap<String, byte[]>());
		FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
				.remove("demandaSeleccionada");
		intervencionsDeDepartamentos = null;
	}

	public void updateIntervencion(RowEditEvent event) {
		Intervencion d = (Intervencion) event.getObject();
		d.setFecha(sdf.format(new Date())
				+ " [Modificada: " + getCurrentTecnico().getNombre() + " " + getCurrentTecnico().getApellidos() + "]"); //$NON-NLS-1$
		new IntervencionDao();
		IntervencionDao.mergeIntervencion(d);
		intervencionsDeDepartamentos = null;
	}

	public void guardarDocumentos() {
		intervencionAmodificar = (Intervencion) FacesContext
				.getCurrentInstance().getExternalContext().getSessionMap()
				.remove("intervencionAmodificar");
		new DocumentoDao();
		if (getDocumentosInt() != null) {
			List<Documento> documentosList = new ArrayList<Documento>();
			for (String nombre : documentosInt.keySet()) {
				Documento documento = new Documento();
				documento.setTipo(nombre);
				documento.setFecha(sdf.format(new Date()));
				documento.setIntervencionBean(intervencionAmodificar);
				if (guardarArchivo(documentosInt.get(nombre), nombre,
						intervencionAmodificar.getIdIntervencion())) {
					new DocumentoDao();
					DocumentoDao.createDocumento(documento);
					documentosList.add(documento);
				}
			}
			if (intervencionAmodificar.getDocumentos() == null) {
				intervencionAmodificar
						.setDocumentos(new ArrayList<Documento>());
			}
			intervencionAmodificar.getDocumentos().addAll(documentosList);
			intervencionAmodificar.setFecha(sdf.format(new Date())
					+ " [Modificada: " + getCurrentTecnico().getNombre() + " "
					+ getCurrentTecnico().getApellidos() + "]");
			new IntervencionDao();
			IntervencionDao.mergeIntervencion(intervencionAmodificar);
		}
		intervencionsDeDepartamentos = null;
		FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
				.put("documentosInt", new HashMap<String, byte[]>());
	}

	public void eliminarDocumento() {
		documentoAEliminar = (Documento) FacesContext.getCurrentInstance()
				.getExternalContext().getSessionMap()
				.remove("documentoAEliminar");
		Intervencion d = documentoAEliminar.getIntervencionBean();
		new DocumentoDao();
		DocumentoDao.deleteDocumento(documentoAEliminar.getIdDocumento());
		new IntervencionDao();
		d.getDocumentos().remove(documentoAEliminar);
		d.setFecha(sdf.format(new Date()) + " [Modificada: "
				+ getCurrentTecnico().getNombre() + " "
				+ getCurrentTecnico().getApellidos() + "]");
		IntervencionDao.mergeIntervencion(d);
		FacesContext context = FacesContext.getCurrentInstance();
		context.addMessage(null,
				new FacesMessage("Exito", "Documento borrado."));
		intervencionsDeDepartamentos = null;
	}

	public void setCurrentTecnico(Tecnico currentTecnico) {
		this.currentTecnico = currentTecnico;
	}

	public Tecnico getCurrentTecnico() {
		return currentTecnico;
	}

	public void setIntervencion(Intervencion intervencion) {
		this.intervencion = intervencion;
	}

	public Intervencion getIntervencion() {
		return intervencion;
	}

	public void setIntervencionSeleccionada(
			Intervencion intervencionSeleccionada) {
		this.intervencionSeleccionada = intervencionSeleccionada;
	}

	public Intervencion getIntervencionSeleccionada() {
		return intervencionSeleccionada;
	}

	public void setDocumentosInt(HashMap<String, byte[]> documentosInt) {
		this.documentosInt = documentosInt;
	}

	@SuppressWarnings("unchecked")
	public HashMap<String, byte[]> getDocumentosInt() {
		documentosInt = (HashMap<String, byte[]>) FacesContext
				.getCurrentInstance().getExternalContext().getSessionMap()
				.get("documentosInt"); //$NON-NLS-1$
		return documentosInt;
	}

	public void setNombresDocumentos(List<String> nombresDocumentos) {
		this.nombresDocumentos = nombresDocumentos;
	}

	public List<String> getNombresDocumentos() {
		nombresDocumentos = new ArrayList<String>();
		nombresDocumentos.addAll(getDocumentosInt().keySet());
		return nombresDocumentos;
	}

	@SuppressWarnings("unchecked")
	public void quitarDocumento() {
		documentosInt = (HashMap<String, byte[]>) FacesContext
				.getCurrentInstance().getExternalContext().getSessionMap()
				.get("documentosInt");
		documentosInt.remove(documento);
		FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
				.put("documentosInt", documentosInt);

	}

	public void setDocumento(String documento) {
		this.documento = documento;
	}

	public String getDocumento() {
		return documento;
	}

	public void setPath(String path) {
		this.path = path;
	}

	public void descargarArchivo() {
		String ruta = Messages.getString("IntervencionsBean.directorio");
		StringTokenizer tokenizer = new StringTokenizer(path, ",");
		String idIntervencion = tokenizer.nextToken();
		String nombre = tokenizer.nextToken();
		ruta += idIntervencion + "\\" + nombre;
		File file = new File(ruta);
		if (file.exists()) {
			try {
				FacesContext facesContext = FacesContext.getCurrentInstance();
				HttpServletResponse response = (HttpServletResponse) facesContext
						.getExternalContext().getResponse();
				String contentDispositionValue = "attachment";
				if (nombre.contains(".doc") || nombre.contains(".docx")) {
					response.setContentType("application/msword");
				} else {
					response.setContentType("application/octet-strem");
				}
				response.setHeader("Content-Disposition",
						contentDispositionValue + ";filename=\"" + nombre
								+ "\"");
				byte[] buffer = new byte[2048];
				int length;
				InputStream inputStream = new FileInputStream(file);
				OutputStream outputStream = response.getOutputStream();

				while ((length = (inputStream.read(buffer))) != -1) {
					outputStream.write(buffer, 0, length);
				}

				response.setStatus(200);

				response.getOutputStream().flush();
				inputStream.close();
				facesContext.responseComplete();
			} catch (IOException e) {
				System.out.println("Error al descargar el archivo: " + ruta);
			}
		}
	}

	public String getPath() {
		return path;
	}

	public void setIntervencionsDeDepartamentos(
			List<Intervencion> intervencionsDeDepartamentos) {
		this.intervencionsDeDepartamentos = intervencionsDeDepartamentos;
	}

	public List<Intervencion> getIntervencionsDeDepartamentos() {
		if (intervencionsDeDepartamentos == null) {
			new IntervencionDao();
			if (getCurrentTecnico().getDepartamentoBean().getNombre()
					.equals("Administracion")
					|| getCurrentTecnico().getDepartamentoBean().getNombre()
							.equals("Direccion")) {
				intervencionsDeDepartamentos = IntervencionDao.findAll();

			} else {
				intervencionsDeDepartamentos = IntervencionDao
						.findIntervencionsDeDepartamento(getCurrentTecnico()
								.getDepartamentoBean().getIdDepartamento());
			}
		}
		return intervencionsDeDepartamentos;
	}

	public void setDocumentoAEliminar(Documento documentoAEliminar) {
		this.documentoAEliminar = documentoAEliminar;
		FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
				.put("documentoAEliminar", documentoAEliminar);
	}

	public Documento getDocumentoAEliminar() {
		return documentoAEliminar;
	}

	public void setIntervencionAmodificar(Intervencion intervencionAmodificar) {
		this.intervencionAmodificar = intervencionAmodificar;
		FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
				.put("intervencionAmodificar", intervencionAmodificar);
	}

	public Intervencion getIntervencionAmodificar() {
		return intervencionAmodificar;
	}

	public void setCadenaUsuario(String cadenaUsuario) {
		this.cadenaUsuario = cadenaUsuario;
	}

	public String getCadenaUsuario() {
		return cadenaUsuario;
	}

	public HashMap<String, String> getNombreDepartamentos() {
		nombreDepartamentos = new HashMap<String, String>();
		new DepartamentoDao();
		List<Departamento> departamentos = DepartamentoDao.findAll();
		for (Departamento dep : departamentos) {
			nombreDepartamentos.put(dep.getNombre(),
					String.valueOf(dep.getIdDepartamento()));
		}
		return nombreDepartamentos;
	}

	public void setCadenaTecnico(String cadenaTecnico) {
		this.cadenaTecnico = cadenaTecnico;
	}

	public String getCadenaTecnico() {
		return cadenaTecnico;
	}

	public void setDepartamento(String departamento) {
		this.departamento = departamento;
		;
	}

	public String getDepartamento() {
		return departamento;
	}

	public void limpiar() {
		cadenaUsuario = "";
		cadenaTecnico = "";
		departamento = "";
		intervencionsDeDepartamentos = null;
	}

	public void buscar() {
		new IntervencionDao();
		int idDep = 0;
		if (cadenaUsuario == null) {
			cadenaUsuario = "";
		}
		if (cadenaTecnico == null) {
			cadenaTecnico = "";
		}
		if (departamento != null && !departamento.equals("")) {
			idDep = Integer.parseInt(departamento);
		}
		List<Intervencion> aux = getIntervencionsDeDepartamentos();
		intervencionsDeDepartamentos = new ArrayList<Intervencion>();
		for (Intervencion intervencion : aux) {
			String usuario = (intervencion.getUsuarioBean().getNombre() + " " + intervencion
					.getUsuarioBean().getApellidos()).toUpperCase();
			String tecnico = (intervencion.getTecnicoBean().getNombre() + " " + intervencion
					.getTecnicoBean().getApellidos()).toUpperCase();
			if (idDep == 0) {
				if (usuario.contains(cadenaUsuario.toUpperCase())
						&& tecnico.toUpperCase().contains(
								cadenaTecnico.toUpperCase())) {
					intervencionsDeDepartamentos.add(intervencion);
				}
			} else {
				int id = intervencion.getTecnicoBean().getDepartamentoBean()
						.getIdDepartamento();
				if (usuario.contains(cadenaUsuario.toUpperCase())
						&& tecnico.contains(cadenaTecnico.toUpperCase())
						&& idDep == id) {
					intervencionsDeDepartamentos.add(intervencion);
				}
			}
		}
	}

	public void setDemanda(Demanda demanda) {
		this.demanda = demanda;
	}

	public Demanda getDemanda() {
		demanda =(Demanda) FacesContext.getCurrentInstance()
		.getExternalContext().getSessionMap()
		.get("demandaSeleccionada");
		return demanda;
	}

	public void setFecha(Date fecha) {
		this.fecha = fecha;
	}

	public Date getFecha() {
		return fecha;
	}

	public void setNuevaOferta(Ofertavivienda nuevaOferta) {
		this.nuevaOferta = nuevaOferta;
	}

	public Ofertavivienda getNuevaOferta() {

		return nuevaOferta;
	}

	public void setOfertaSeleccionada(Ofertavivienda ofertaSeleccionada) {
		this.ofertaSeleccionada = ofertaSeleccionada;
		FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
				.put("ofertaSeleccionada", ofertaSeleccionada);
	}

	public Ofertavivienda getOfertaSeleccionada() {
		ofertaSeleccionada = (Ofertavivienda) FacesContext.getCurrentInstance()
				.getExternalContext().getSessionMap().get("ofertaSeleccionada");
		return ofertaSeleccionada;
	}

	public void setNombreContacto(String nombreContacto) {
		this.nombreContacto = nombreContacto;
	}

	public String getNombreContacto() {
		return nombreContacto;
	}

	public List<String> complete(String query) {
		new ContactoViviendaDao();
		List<Contactovivienda> contactos = ContactoViviendaDao
				.findContactoviviendaByName(query);
		List<String> suggestions = new ArrayList<String>();
		for (Contactovivienda contacto : contactos) {
			suggestions.add(contacto.getNombre());
		}
		return suggestions;
	}

	public void setIntervencionOferta(Intervencion intervencionOferta) {
		this.intervencionOferta = intervencionOferta;
		FacesContext.getCurrentInstance().getExternalContext().getSessionMap()
				.put("intervencionOferta", intervencionOferta);
	}

	public Intervencion getIntervencionOferta() {
		intervencionOferta = (Intervencion) FacesContext.getCurrentInstance()
				.getExternalContext().getSessionMap().get("intervencionOferta");
		return intervencionOferta;
	}
}
